package com.example.springbootredis.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * Redis操作
 * @author donxing
 */
//@Repository
public class RedisDao {

	private Logger log = LoggerFactory.getLogger(RedisDao.class);

	@Autowired
	protected RedisTemplate<String, String> redisTemplate;

	public void put(String key, String hashKey, Map<String, Object> value) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		hash.put(key, hashKey, value);
	}

	public void put(String key, String hashKey, Object value) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		hash.put(key, hashKey, value);
	}

	public Boolean putIfAbsent(String key, String hashKey, Object value) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		return hash.putIfAbsent(key, hashKey, value);
	}

	public void putAll(String key, Map<String, Object> value) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		hash.putAll(key, value);
	}

	public Map<String, Object> entries(String key) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		return hash.entries(key);
	}

	public Object get(String key, String hashKey) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		return hash.get(key,hashKey);
	}

	public void flushDb() {
		redisTemplate.getConnectionFactory().getConnection().flushDb();
		log.info("redis flushDb is ok.");
	}

	public void delete(String key, Object hashKey) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		hash.delete(key, hashKey);
	}

	public Collection<Object> multiGet(String key, Collection<String> hashKeys) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		return hash.multiGet(key, hashKeys);
	}

	public Set<String> keys(String key) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		return hash.keys(key);
	}

	public Long size(String key) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		return hash.size(key);
	}

	public Collection<Object> values(String key) {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		return hash.values(key);
	}

	public RedisOperations<String, ?> getOperations() {
		HashOperations<String, String, Object> hash = redisTemplate.opsForHash();
		return hash.getOperations();
	}

	public Long addSetValue(String key, String ... values) {
		SetOperations<String, String> set = redisTemplate.opsForSet();
		return set.add(key, values);
	}

	public String getSetValue(String key) {
		SetOperations<String, String> set = redisTemplate.opsForSet();
		return set.pop(key);
	}

	public void delSetValue(String key, Object hashKey) {
		SetOperations<String, String> set = redisTemplate.opsForSet();
		set.remove(key, hashKey);
	}
	
	public boolean setNX(String key, String value) {
		boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {  
			@Override
            public Boolean doInRedis(RedisConnection connection)  
                    throws DataAccessException {  
                return connection.setNX(key.getBytes(), value.getBytes());  
            }  
        });  
        return result;
	}
	
	public boolean set(String key, String value) {
		boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {  
			@Override
            public Boolean doInRedis(RedisConnection connection)  
                    throws DataAccessException {  
                connection.set(key.getBytes(), value.getBytes());  
                return true;
            }  
        });  
        return result;
	}
	
	public String getValue(String key) {
		String result ="";
		try {
			result=redisTemplate.execute(new RedisCallback<String>() { 
				@Override
	            public String doInRedis(RedisConnection connection)  
	                    throws DataAccessException {  
	                return new String(connection.get(key.getBytes()));
	            }  
	        });  
		} catch (Exception e) {
			log.info("RedisDao getValue Exception:"+e.getMessage());
		}
        return result;
	}
	
	public Long ttl(String key) {
		Long result=null;
		try {
			result= redisTemplate.execute(new RedisCallback<Long>() {
				@Override
	            public Long doInRedis(RedisConnection connection)  
	                    throws DataAccessException {  
	            	return connection.ttl(key.getBytes());
	            }  
	        }); 
		} catch (Exception e) {
			log.info("RedisDao ttl Exception:"+e.getMessage());
		}
		return result;
	}
	
	public boolean expire(String key, Long seconds) {
		redisTemplate.execute(new RedisCallback<Boolean>() {  
			@Override
            public Boolean doInRedis(RedisConnection connection)  
                    throws DataAccessException {  
                connection.expire(key.getBytes(), seconds);
                return true;
            }  
        });  
        return false;
	}
	
	public void delValue(String key) {
		redisTemplate.execute(new RedisCallback<Boolean>() { 
			@Override
            public Boolean doInRedis(RedisConnection connection)  
                    throws DataAccessException {  
                connection.del(key.getBytes()); 
                return true;
            }  
        });  
	}

	public RedisTemplate<String, String> getRedisTemplate() {
		return redisTemplate;
	}

	public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}
	
//	public Long getID(){
//		Long idnum=this.redisTemplate.opsForValue().increment(Constant.REDIS_KEY, 1) % 65536;
//		Long sec=System.currentTimeMillis()-1420041600;
//		return sec*16777216 + 1*1048576 + 1*65536 + idnum;
//	}
	
}
